package com.edu.exam.entity.grading;

import com.edu.exam.enums.grading.GradeType;
import com.edu.exam.enums.StatisticsType;
import com.edu.exam.enums.grading.StatisticsPeriod;
import com.edu.exam.enums.grading.StatisticsStatus;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;

/**
 * 成绩统计实体类
 * [所属模块] G-07 成绩统计分析模块
 *
 * <p>成绩统计实体用于存储和管理成绩的统计分析数据，包含
 * 基础统计、分布统计、排名统计、趋势统计等。为成绩分析提供全面的数据支持。</p>
 *
 * <p>核心功能：
 * - 基础统计：计算平均分、最高分、最低分等基础指标
 * - 分布统计：统计分数分布区间和等级分布
 * - 排名统计：计算排名数据和百分位信息
 * - 趋势统计：分析成绩变化趋势
 * - 质量分析：提供教学质量分析指标</p>
 *
 * @author 系统生成
 * @version 1.0
 * @since 2025-11-10
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@Entity
@EntityListeners(AuditingEntityListener.class)
public class GradeStatistics {

    /**
     * 主键ID
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    /**
     * 课程ID
     *
     * <p>统计关联的课程ID。</p>
     */
    @Column(name = "course_id", nullable = false, length = 50)
    private String courseId;

    /**
     * 班级ID
     *
     * <p>统计关联的班级ID，为空表示全课程统计。</p>
     */
    @Column(name = "class_id", length = 50)
    private String classId;

    /**
     * 学年
     *
     * <p>统计的学年，格式：YYYY-YYYY。</p>
     */
    @Column(name = "academic_year", length = 20)
    private String academicYear;

    /**
     * 学期
     *
     * <p>统计的学期。</p>
     */
    @Column(name = "semester", length = 20)
    private String semester;

    /**
     * 成绩类型
     *
     * <p>统计的成绩类型。
     * 支持的类型：DAILY（平时成绩）、MIDTERM（期中成绩）、FINAL（期末成绩）、TOTAL（总评成绩）</p>
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "grade_type", nullable = false, length = 20)
    private GradeType gradeType;

    /**
     * 统计类型
     *
     * <p>统计计算的类型。
     * 支持的类型：BASIC（基础统计）、DISTRIBUTION（分布统计）、RANKING（排名统计）、TREND（趋势统计）、QUALITY（质量分析）</p>
     */
    @Column(name = "statistics_type", nullable = false, length = 30)
    private String statisticsType = "BASIC";

    /**
     * 统计周期
     *
     * <p>统计计算的时间周期。
     * 支持的周期：DAILY（每日）、WEEKLY（每周）、MONTHLY（每月）、QUARTERLY（每季度）、SEMESTER（每学期）、YEARLY（每年）、CUSTOM（自定义）</p>
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "statistics_period", length = 20)
    private StatisticsPeriod statisticsPeriod = StatisticsPeriod.SEMESTER;

    /**
     * 统计开始时间
     *
     * <p>统计范围的开始时间。</p>
     */
    @Column(name = "period_start_time", nullable = false)
    private LocalDateTime periodStartTime;

    /**
     * 统计结束时间
     *
     * <p>统计范围的结束时间。</p>
     */
    @Column(name = "period_end_time", nullable = false)
    private LocalDateTime periodEndTime;

    /**
     * 计算时间
     *
     * <p>统计计算的时间。</p>
     */
    @Column(name = "calculation_time", nullable = false)
    private LocalDateTime calculationTime;

    /**
     * 总人数
     *
     * <p>参与统计的学生总数。</p>
     */
    @Column(name = "total_students", nullable = false)
    private Integer totalStudents = 0;

    /**
     * 有效成绩数
     *
     * <p>有效成绩的数量。</p>
     */
    @Column(name = "valid_grades", nullable = false)
    private Integer validGrades = 0;

    /**
     * 平均分
     *
     * <p>成绩平均值。</p>
     */
    @Column(name = "average_score", precision = 10, scale = 2)
    private BigDecimal averageScore;

    /**
     * 中位数
     *
     * <p>成绩中位数。</p>
     */
    @Column(name = "median_score", precision = 10, scale = 2)
    private BigDecimal medianScore;

    /**
     * 众数
     *
     * <p>成绩众数。</p>
     */
    @Column(name = "mode_score", precision = 10, scale = 2)
    private BigDecimal modeScore;

    /**
     * 最高分
     *
     * <p>成绩最高分。</p>
     */
    @Column(name = "max_score", precision = 10, scale = 2)
    private BigDecimal maxScore;

    /**
     * 最低分
     *
     * <p>成绩最低分。</p>
     */
    @Column(name = "min_score", precision = 10, scale = 2)
    private BigDecimal minScore;

    /**
     * 极差
     *
     * <p>最高分与最低分的差值。</p>
     */
    @Column(name = "score_range", precision = 10, scale = 2)
    private BigDecimal scoreRange;

    /**
     * 标准差
     *
     * <p>成绩标准差。</p>
     */
    @Column(name = "standard_deviation", precision = 10, scale = 4)
    private BigDecimal standardDeviation;

    /**
     * 方差
     *
     * <p>成绩方差。</p>
     */
    @Column(name = "variance", precision = 12, scale = 4)
    private BigDecimal variance;

    /**
     * 偏度
     *
     * <p>成绩分布的偏度。</p>
     */
    @Column(name = "skewness", precision = 10, scale = 4)
    private BigDecimal skewness;

    /**
     * 峰度
     *
     * <p>成绩分布的峰度。</p>
     */
    @Column(name = "kurtosis", precision = 10, scale = 4)
    private BigDecimal kurtosis;

    /**
     * 优秀人数
     *
     * <p>优秀成绩的学生人数。</p>
     */
    @Column(name = "excellent_count", nullable = false)
    private Integer excellentCount = 0;

    /**
     * 良好人数
     *
     * <p>良好成绩的学生人数。</p>
     */
    @Column(name = "good_count", nullable = false)
    private Integer goodCount = 0;

    /**
     * 及格人数
     *
     * <p>及格成绩的学生人数。</p>
     */
    @Column(name = "pass_count", nullable = false)
    private Integer passCount = 0;

    /**
     * 不及格人数
     *
     * <p>不及格成绩的学生人数。</p>
     */
    @Column(name = "fail_count", nullable = false)
    private Integer failCount = 0;

    /**
     * 优秀率
     *
     * <p>优秀成绩的百分比。</p>
     */
    @Column(name = "excellent_rate", precision = 5, scale = 2)
    private BigDecimal excellentRate;

    /**
     * 良好率
     *
     * <p>良好成绩的百分比。</p>
     */
    @Column(name = "good_rate", precision = 5, scale = 2)
    private BigDecimal goodRate;

    /**
     * 及格率
     *
     * <p>及格成绩的百分比。</p>
     */
    @Column(name = "pass_rate", precision = 5, scale = 2)
    private BigDecimal passRate;

    /**
     * 分数区间分布
     *
     * <p>各分数区间的分布情况，JSON格式存储。</p>
     */
    @Column(name = "score_distribution", columnDefinition = "TEXT")
    private String scoreDistribution;

    /**
     * 等级分布
     *
     * <p>各等级的分布情况，JSON格式存储。</p>
     */
    @Column(name = "grade_distribution", columnDefinition = "TEXT")
    private String gradeDistribution;

    /**
     * 百分位数
     *
     * <p>关键百分位数信息，JSON格式存储。</p>
     */
    @Column(name = "percentiles", columnDefinition = "TEXT")
    private String percentiles;

    /**
     * 排名信息
     *
     * <p>排名统计信息，JSON格式存储。</p>
     */
    @Column(name = "ranking_info", columnDefinition = "TEXT")
    private String rankingInfo;

    /**
     * 趋势数据
     *
     * <p>历史趋势数据，JSON格式存储。</p>
     */
    @Column(name = "trend_data", columnDefinition = "TEXT")
    private String trendData;

    /**
     * 质量指标
     *
     * <p>教学质量分析指标，JSON格式存储。</p>
     */
    @Column(name = "quality_indicators", columnDefinition = "TEXT")
    private String qualityIndicators;

    /**
     * 优秀阈值
     *
     * <p>优秀成绩的分数线。</p>
     */
    @Column(name = "excellent_threshold", precision = 5, scale = 2)
    private BigDecimal excellentThreshold = BigDecimal.valueOf(90.00);

    /**
     * 良好阈值
     *
     * <p>良好成绩的分数线。</p>
     */
    @Column(name = "good_threshold", precision = 5, scale = 2)
    private BigDecimal goodThreshold = BigDecimal.valueOf(80.00);

    /**
     * 及格阈值
     *
     * <p>及格成绩的分数线。</p>
     */
    @Column(name = "pass_threshold", precision = 5, scale = 2)
    private BigDecimal passThreshold = BigDecimal.valueOf(60.00);

    /**
     * 统计状态
     *
     * <p>统计计算的当前状态。
     * 支持的状态：PENDING（待计算）、CALCULATING（计算中）、COMPLETED（已完成）、FAILED（失败）、OUTDATED（已过期）</p>
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "statistics_status", nullable = false, length = 20)
    private StatisticsStatus statisticsStatus = StatisticsStatus.PENDING;

    /**
     * 计算耗时
     *
     * <p>统计计算的耗时（毫秒）。</p>
     */
    @Column(name = "calculation_duration_ms")
    private Long calculationDurationMs;

    /**
     * 计算错误信息
     *
     * <p>计算失败时的错误信息。</p>
     */
    @Column(name = "calculation_error", columnDefinition = "TEXT")
    private String calculationError;

    /**
     * 数据版本
     *
     * <p>统计数据的版本号。</p>
     */
    @Column(name = "data_version", length = 20)
    private String dataVersion = "1.0";

    /**
     * 统计标签
     *
     * <p>JSON格式的统计标签，用于分类和过滤。</p>
     */
    @Column(name = "statistics_tags", columnDefinition = "TEXT")
    private String statisticsTags;

    /**
     * 统计备注
     *
     * <p>统计计算的备注信息。</p>
     */
    @Column(name = "statistics_notes", columnDefinition = "TEXT")
    private String statisticsNotes;

    /**
     * 附加数据
     *
     * <p>JSON格式的附加统计数据。</p>
     */
    @Column(name = "additional_data", columnDefinition = "TEXT")
    private String additionalData;

    // ===== 标准审计字段 =====

    /**
     * 创建时间
     */
    @CreationTimestamp
    @Column(name = "created_time", nullable = false, updatable = false)
    private LocalDateTime createdTime;

    /**
     * 更新时间
     */
    @UpdateTimestamp
    @Column(name = "updated_time", nullable = false)
    private LocalDateTime updatedTime;

    /**
     * 版本号（乐观锁）
     */
    @Version
    @Column(name = "version", nullable = false)
    private Long version = 0L;

    /**
     * 是否删除
     */
    @Column(name = "is_deleted", nullable = false)
    private Boolean isDeleted = false;
}
